package utils

// http客户端相关实现

import (
	"encoding/json"
	"errors"
	"fmt"
	"io/ioutil"
	"net/http"
	"strings"
	"time"
)

type HttpClient struct {
	Protocol    string
	Ip          string
	Port        int
	Path        string
	Method      string
	TimeOut     time.Duration
	ContentType map[string]string
}

// SendMessageAndGetResult 发送信息并且接收返回值，要求 StatusCode 必须等于200
func (a HttpClient) SendMessageAndGetResult(params interface{}, result *interface{}) (err error) {
	var b []byte
	b, err = json.Marshal(params)
	if err != nil {
		return
	}
	var req *http.Request
	req, err = http.NewRequest(a.Method, fmt.Sprintf("%s://%s:%d%s", a.Protocol, a.Ip, a.Port, a.Path), strings.NewReader(string(b)))
	if err != nil {
		return err
	}
	if len(a.ContentType) > 0 {
		for i := range a.ContentType {
			req.Header.Add(i, a.ContentType[i])
		}
	}
	client := http.Client{}
	client.Timeout = a.TimeOut
	var rq *http.Response
	rq, err = client.Do(req)
	if err != nil {
		return err
	}
	if rq.StatusCode != http.StatusOK {
		return errors.New("StatusCode is not 200")
	}
	defer rq.Body.Close()
	b, err = ioutil.ReadAll(rq.Body)
	if err != nil {
		return err
	}
	err = json.Unmarshal(b, &result)
	return err
}

// SendMessageAndResponse204 发送消息，并且没有返回值
func (a HttpClient) SendMessageAndResponse204(params interface{}) (err error) {
	var b []byte
	b, err = json.Marshal(params)
	if err != nil {
		return
	}
	var req *http.Request
	req, err = http.NewRequest(a.Method, fmt.Sprintf("%s://%s:%d%s", a.Protocol, a.Ip, a.Port, a.Path), strings.NewReader(string(b)))
	if err != nil {
		return err
	}
	if len(a.ContentType) > 0 {
		for i := range a.ContentType {
			req.Header.Add(i, a.ContentType[i])
		}
	}
	client := http.Client{}
	client.Timeout = a.TimeOut
	var rq *http.Response
	rq, err = client.Do(req)
	if err != nil {
		return err
	}
	defer rq.Body.Close()
	if rq.StatusCode == http.StatusNoContent {
		return nil
	}
	return errors.New("StatusCode is not 204")
}
